﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using MDCAdminTool.Controls;

namespace MDCAdminTool.Commands
{
    public abstract class AsyncCommandBindingBase : CommandBinding
    {
        private BackgroundWorker bw;
        private AsyncProgressBar prg;

        protected bool isWorking = false;

        protected AsyncCommandBindingBase()
        {
            bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.DoWork += bw_DoWork;
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;

            prg = Application.Current.Properties["PowerShellProgressBar"] as AsyncProgressBar;

            CanExecute += OnCoreCanExecute;
            Executed   += OnCoreExecuted;
        }

        void bw_RunWorkerCompleted( object sender , RunWorkerCompletedEventArgs e )
        {
            if ( prg != null )
                prg.Stop();
        }
        void bw_DoWork( object sender , DoWorkEventArgs e )
        {
            isWorking = true;
            try
            {
                OnExecuted(sender, e.Argument as ExecutedRoutedEventArgs);
            }
            finally 
            {
                isWorking = false;
            }

            // Forcing the CommandManager to raise the RequerySuggested event
            Application.Current.Dispatcher.Invoke(new Action(() => CommandManager.InvalidateRequerySuggested()));
        }

        protected void OnCoreExecuted( object sender , ExecutedRoutedEventArgs e )
        {
            if( bw.IsBusy ) return;

            bw.RunWorkerAsync( e );
            
            if( prg == null )
                prg = Application.Current.Properties["PowerShellProgressBar"] as AsyncProgressBar;

            if( prg != null )
                prg.Start();
        }

        protected void OnCoreCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (isWorking)
                e.CanExecute = false;
            else
                OnCanExecute(sender, e);
        }
        
        protected virtual void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        protected abstract void OnExecuted( object sender , ExecutedRoutedEventArgs e );

    	protected MessageBoxResult ShowConfirmationBox(string messageText)
    	{
    		MessageBoxResult result = MessageBoxResult.No;

    		Application.Current.Dispatcher.Invoke(
    			new Action(
    				() =>
    					{
    						result = MessageBox.Show(Application.Current.MainWindow, messageText, "", MessageBoxButton.YesNo,
    						                         MessageBoxImage.Question,
    						                         MessageBoxResult.No, MessageBoxOptions.None);
    					}
    				));
    		return result;
    	}
    }
}